import { ChangeDetectorRef, Component, EventEmitter, HostBinding, Injector, Input, OnInit, Output, TemplateRef, ViewChild } from '@angular/core';
import { NotifyService } from '@farris/ui-notify';
import { TreeNode, TreeTableColumn, TreeTableComponent } from '@farris/ui-treetable';
import { DomService, WebCmdService } from '@farris/designer-services';
import { cloneDeep } from 'lodash-es';
import { ElementPropertyConfig, PropertyChangeObject } from '@farris/ide-property-panel';
import { ToolBarItemProp } from '../../../../../command/toolbar/component/toolbaritem/property/property-config';
import { ControlService } from '.././../../../../../service/control.service';

@Component({
    selector: 'app-page-toolbar-editor',
    templateUrl: './page-toolbar-editor.component.html',
    styleUrls: ['./page-toolbar-editor.component.css']
})

export class PageToolbarEditorComponent implements OnInit {

    @Input() editorParams: { controlId: string, viewModelId: string };
    @Output() closeModal = new EventEmitter<any>();
    @Output() submitModal = new EventEmitter<any>();

    @ViewChild('modalFooter') modalFooter: TemplateRef<any>;
    modalConfig = {
        title: '工具栏编辑器',
        width: 950,
        height: 700,
        showButtons: true,
        showMaxButton: true
    };

    /** 左侧树实例 */
    @ViewChild('leftTree') leftTree: TreeTableComponent;

    /** 左侧树数据：当前表单所有的工具栏按钮 */
    leftTreeData: TreeNode[] = [];

    /** 树表列配置 */
    treeColumns = [{ field: 'text', title: '名称' }];
    @ViewChild('textColTpl') textColTpl: TemplateRef<any>;
    rightTreeColumns: TreeTableColumn[] = [];



    /** 右侧树实例 */
    @ViewChild('rightTree') rightTree: TreeTableComponent;

    /** 右侧树数据：当前控件已选择的按钮 */
    rightTreeData: TreeNode[] = [];
    /** 右侧选择的行 */
    selectedRightNode: TreeNode;

    /** 当前模式下控件的按钮配置 */
    toolbarConfig = [] as string[];
    /** 全部按钮 */
    toolbarItems = [] as any[];

    @HostBinding('class')
    class = 'h-100 d-flex flex-fill';

    noDataMoveMessage = '请选择要移动的数据。';

    /** 当前所有被占用的按钮ID */
    occupiedButtonIdList = [];

    /** 属性面板配置 */
    propertyConfig: ElementPropertyConfig[] = [];

    /** 属性面板值 */
    propertyData;

    /** 当前表单的展示模式，弹出类modal/独立页签类page/侧边滑出类slide */
    currentFormMode = 'page';

    private toolbarItemProp: ToolBarItemProp;
    constructor(
        private notifyServ: NotifyService,
        private domService: DomService,
        private controlService: ControlService,
        private injector: Injector,
        private cd: ChangeDetectorRef,
        private webCmdService: WebCmdService) {



    }
    ngOnInit() {
        this.currentFormMode = this.domService.module.showType || 'page';
        const comp = this.domService.getComponentByVMId(this.editorParams.viewModelId);
        if (comp && comp.showType) {
            this.currentFormMode = comp.showType;
        }

        this.rightTreeColumns = [{
            field: 'text',
            title: '名称',
            template: this.textColTpl
        }];
        const toolbar = this.domService.module.toolbar;
        if (!toolbar || !toolbar.items || !toolbar.items[this.editorParams.viewModelId]) {
            return;
        }
        this.toolbarItems = cloneDeep(toolbar.items[this.editorParams.viewModelId]);
        if (toolbar.configs && toolbar.configs[this.currentFormMode]) {
            this.toolbarConfig = cloneDeep(toolbar.configs[this.currentFormMode][this.editorParams.controlId] || []);
            this.getOccupiedButtons();
        }

        this.leftTreeData = this.assembleToolbarItemsToTree(this.toolbarItems);

        const selectedToolbarItems = [];
        this.toolbarConfig.forEach(buttonId => {
            const buttonInfo = this.toolbarItems.find(item => buttonId === item.id);
            if (buttonInfo) {
                selectedToolbarItems.push(buttonInfo);
            }
        });

        this.rightTreeData = this.assembleToolbarItemsToTree(selectedToolbarItems);

        this.toolbarItemProp = new ToolBarItemProp(this.injector, this.editorParams.viewModelId);
    }

    private assembleToolbarItemsToTree(buttons: any, level = 0) {
        const treeData: TreeNode[] = [];
        buttons.forEach(button => {

            // 子级按钮
            let children = [];
            if (button.items) {
                children = this.assembleToolbarItemsToTree(button.items, level + 1);
            }

            treeData.push({
                data: button,
                children,
                expanded: level > 0
            });
        });

        return treeData;
    }

    /**
     * 获取当前展示模式下 所有被占用的按钮
     */
    getOccupiedButtons() {
        this.occupiedButtonIdList = [];
        const toolbar = this.domService.module.toolbar;
        const configsInCurrentModel = toolbar.configs[this.currentFormMode];

        if (!configsInCurrentModel) {
            return;
        }
        for (const controlId of Object.keys(configsInCurrentModel)) {

            if (configsInCurrentModel[controlId].length > 0) {
                this.occupiedButtonIdList.push(...configsInCurrentModel[controlId]);
            }
            // if (controlId !== this.editorParams.controlId) {
            //     this.occupiedByOtherControlButtonIdList.push(...configsInCurrentModel[controlId]);
            // }

        }

    }
    /**
     * 左侧树节点是否可勾选
     */
    canChecked(treeNode: any) {
        if (!treeNode.selectable || !!treeNode.parent) {
            return false;
        }

        return !this.occupiedButtonIdList.includes(treeNode.data.id);
    }

    /**
     * 左侧树行颜色
     */
    getTdStyleColor(canCheck: boolean, treeNode: any) {
        // 判断子级按钮的颜色
        if (!canCheck && treeNode.parent) {
            const rootNode = this.getRootNode(treeNode);
            const parentCanCheck = this.canChecked(rootNode);
            if (parentCanCheck) {
                canCheck = true;
            }
        }

        return canCheck ? '#333' : '#a6a6a6';
    }
    /**
     * 子级按钮的颜色：与所属顶层按钮一致
     */
    getRootNode(treeNode: any) {
        const parentNode = treeNode.parent;
        if (parentNode) {
            return this.getRootNode(parentNode);
        } else {
            return treeNode;
        }
    }
    /**
     * 选择右侧行
     */
    selectRightNode(rowNode: any) {
        this.selectedRightNode = rowNode.node;

        this.propertyData = this.selectedRightNode.data;

        this.propertyConfig = this.toolbarItemProp.getPropertyConfigInTree(this.editorParams.viewModelId, false,
            this.selectedRightNode);

        this.cd.detectChanges();
    }

    /**
     * 右移
     */
    moveToRight() {
        const leftChecks = this.leftTree.checkeds;
        if (!leftChecks || leftChecks.length === 0) {
            this.notifyServ.warning(this.noDataMoveMessage);
            return;
        }
        const needMoveButtons = [];
        leftChecks.forEach(checkNode => {
            if (checkNode.parent) {
                return;
            }
            needMoveButtons.push(checkNode.data);
            this.occupiedButtonIdList.push(checkNode.data.id);
        });
        const rightNewTreeNodes = this.assembleToolbarItemsToTree(needMoveButtons);
        this.rightTreeData.push(...rightNewTreeNodes);

        this.rightTree.loadData(this.rightTreeData);
        this.leftTree.clearAll();


    }
    /**
     * 全部右移
     */
    moveAllToRight() {
        const needMoveButtons = [];
        this.leftTree.data.forEach(treeNode => {
            if (this.canChecked(treeNode)) {
                needMoveButtons.push(treeNode.data);
                this.occupiedButtonIdList.push(treeNode.data.id);
            }
        });
        const rightNewTreeNodes = this.assembleToolbarItemsToTree(needMoveButtons);
        this.rightTreeData.push(...rightNewTreeNodes);

        this.rightTree.loadData(this.rightTreeData);
        this.leftTree.clearAll();
    }

    /**
     * 左移
     */
    moveToLeft() {

        if (!this.selectedRightNode) {
            this.notifyServ.warning(this.noDataMoveMessage);
            return;
        }
        if (this.selectedRightNode.parent) {
            this.notifyServ.warning('请选择根节点');
            return;
        }
        const index = this.rightTreeData.findIndex(d => d.data.id === this.selectedRightNode.data.id);
        if (index < 0) {
            return;
        }
        this.rightTreeData.splice(index, 1);

        this.rightTree.loadData(this.rightTreeData);
        this.rightTree.clearSelections();


        this.occupiedButtonIdList = this.occupiedButtonIdList.filter(id => id !== this.selectedRightNode.data.id);

        this.propertyConfig = [];
        this.selectedRightNode = null;
    }

    /**
     * 全部删除
     */
    moveAllToLeft() {
        const buttonIds = this.rightTreeData.map(d => d.data.id);
        this.occupiedButtonIdList = this.occupiedButtonIdList.filter(id => !buttonIds.includes(id));


        this.rightTreeData.length = 0;
        this.rightTree.loadData(this.rightTreeData);
        this.rightTree.clearSelections();

        this.propertyConfig = [];
        this.selectedRightNode = null;
    }

    /**
     * 置顶
     */
    moveTop() {
        if (!this.selectedRightNode) {
            this.notifyServ.warning(this.noDataMoveMessage);
            return;
        }
        const parentNode = this.selectedRightNode.parent;
        const siblingNodes = parentNode ? parentNode.children : this.rightTreeData;

        const index = siblingNodes.findIndex(node => node.data.id === this.selectedRightNode.data.id);
        if (index < 1) {
            return;
        }
        siblingNodes.splice(index, 1);
        siblingNodes.splice(0, 0, this.selectedRightNode);

        this.rightTree.loadData(this.rightTreeData);

        // 重新选中行
        const newRowNode = this.rightTree.findRowNode(this.selectedRightNode.data.id);
        if (newRowNode) {
            newRowNode.isSelected = true;
        }
        // 同步左侧树子级节点的顺序
        const leftTreeNode = this.leftTree.serializedValue.find(v => v.node.data.id === this.selectedRightNode.data.id);
        if (parentNode) {
            const leftParentNode = leftTreeNode.parent;

            const leftIndex = leftParentNode.children.findIndex(node => node.data.id === this.selectedRightNode.data.id);
            if (leftIndex < 1) {
                return;
            }
            leftParentNode.children.splice(leftIndex, 1);
            leftParentNode.children.splice(0, 0, leftTreeNode.node);

            this.leftTree.loadData(this.leftTreeData);

        }
    }
    /**
     * 上移
     */
    moveUp() {
        if (!this.selectedRightNode) {
            this.notifyServ.warning(this.noDataMoveMessage);
            return;
        }
        const parentNode = this.selectedRightNode.parent;
        const siblingNodes = parentNode ? parentNode.children : this.rightTreeData;

        const index = siblingNodes.findIndex(node => node.data.id === this.selectedRightNode.data.id);
        if (index < 1) {
            return;
        }
        siblingNodes.splice(index, 1);
        siblingNodes.splice(index - 1, 0, this.selectedRightNode);

        this.rightTree.loadData(this.rightTreeData);

        // 同步左侧树子级节点的顺序
        const leftTreeNode = this.leftTree.serializedValue.find(v => v.node.data.id === this.selectedRightNode.data.id);
        if (parentNode) {
            const leftParentNode = leftTreeNode.parent;

            const leftIndex = leftParentNode.children.findIndex(node => node.data.id === this.selectedRightNode.data.id);
            if (leftIndex < 1) {
                return;
            }
            leftParentNode.children.splice(leftIndex, 1);
            leftParentNode.children.splice(leftIndex - 1, 0, leftTreeNode.node);

            this.leftTree.loadData(this.leftTreeData);

        }
        // else {
        //     const leftIndex = this.leftTreeData.findIndex(node => node.data.id === this.selectedRightNode.data.id);
        //     if (leftIndex < 1) {
        //         return;
        //     }
        //     this.leftTreeData.splice(index, 1);
        //     this.leftTreeData.splice(index - 1, 0, leftTreeNode.node);
        // }
        // this.leftTree.loadData(this.leftTreeData);
    }
    /**
     * 下移
     */
    moveDown() {
        if (!this.selectedRightNode) {
            this.notifyServ.warning(this.noDataMoveMessage);
            return;
        }
        const parentNode = this.selectedRightNode.parent;
        const siblingNodes = parentNode ? parentNode.children : this.rightTreeData;

        const index = siblingNodes.findIndex(node => node.data.id === this.selectedRightNode.data.id);
        if (index === siblingNodes.length - 1) {
            return;
        }
        siblingNodes.splice(index, 1);
        siblingNodes.splice(index + 1, 0, this.selectedRightNode);

        this.rightTree.loadData(this.rightTreeData);

        // 同步左侧树子级节点的顺序
        const leftTreeNode = this.leftTree.serializedValue.find(v => v.node.data.id === this.selectedRightNode.data.id);
        if (parentNode) {
            const leftParentNode = leftTreeNode.parent;

            const leftIndex = leftParentNode.children.findIndex(node => node.data.id === this.selectedRightNode.data.id);
            if (leftIndex === leftParentNode.children.length - 1) {
                return;
            }
            leftParentNode.children.splice(leftIndex, 1);
            leftParentNode.children.splice(leftIndex + 1, 0, leftTreeNode.node);

            this.leftTree.loadData(this.leftTreeData);

        }
    }

    /**
     * 置底
     */
    moveBottom() {
        if (!this.selectedRightNode) {
            this.notifyServ.warning(this.noDataMoveMessage);
            return;
        }
        const parentNode = this.selectedRightNode.parent;
        const siblingNodes = parentNode ? parentNode.children : this.rightTreeData;

        const index = siblingNodes.findIndex(node => node.data.id === this.selectedRightNode.data.id);
        if (index === siblingNodes.length - 1) {
            return;
        }
        siblingNodes.splice(index, 1);
        siblingNodes.push(this.selectedRightNode);

        this.rightTree.loadData(this.rightTreeData);

        // 同步左侧树子级节点的顺序
        const leftTreeNode = this.leftTree.serializedValue.find(v => v.node.data.id === this.selectedRightNode.data.id);
        if (parentNode) {
            const leftParentNode = leftTreeNode.parent;

            const leftIndex = leftParentNode.children.findIndex(node => node.data.id === this.selectedRightNode.data.id);
            if (leftIndex === leftParentNode.children.length - 1) {
                return;
            }
            leftParentNode.children.splice(leftIndex, 1);
            leftParentNode.children.push(leftTreeNode.node);

            this.leftTree.loadData(this.leftTreeData);

        }
    }


    /**
     * 新增按钮
     */
    addButton() {
        const newButtonData = this.controlService.getControlMetaData('ToolBarItem');
        const radomNum = Math.random().toString().substr(2, 4);
        newButtonData.id = 'toolBarItem_' + radomNum;
        newButtonData.text = '新增按钮_' + radomNum;

        this.leftTreeData.push({ data: newButtonData, children: [], expanded: false });

        this.leftTree.loadData(this.leftTreeData);
    }
    /**
     * 删除按钮
     */
    deleteButton() {
        const leftChecks = this.leftTree.checkeds;
        if (!leftChecks || leftChecks.length === 0) {
            this.notifyServ.warning('请勾选要删除的数据');
            return;
        }

        for (const checkNode of leftChecks) {
            if (checkNode.parent) {
                return;
            }
            const occupiedControlId = this.checkCanDeleteButton(checkNode.data.id);
            if (occupiedControlId) {
                this.notifyServ.warning('【' + checkNode.data.text + '】已经在ID为' + occupiedControlId + '的控件中使用，请先在控件中移除');
            } else {

                const index = this.leftTreeData.findIndex(d => d.data.id === checkNode.data.id);
                if (index > -1) {
                    this.leftTreeData.splice(index, 1);
                }

            }
        }
        this.leftTree.loadData(this.leftTreeData);
    }

    checkCanDeleteButton(buttonId: string) {
        const toolbar = this.domService.module.toolbar;
        if (!toolbar || !toolbar.configs) {
            return;
        }

        const configsInCurrentModel = toolbar.configs[this.currentFormMode];
        // for (const formModel of Object.keys(toolbar.configs)) {
        //     const configsInCurrentModel = toolbar.configs[formModel];
        if (!configsInCurrentModel) {
            return;
        }
        for (const controlId of Object.keys(configsInCurrentModel)) {
            if (controlId === this.editorParams.controlId) {
                continue;
            }
            if (configsInCurrentModel[controlId].length > 0) {
                if (configsInCurrentModel[controlId].includes(buttonId)) {
                    return controlId;
                }
            }

        }
        // }
        return;
    }

    /**
     * 添加子级按钮
     */
    addChildButton(treeNode: any) {

        const newButtonData = this.controlService.getControlMetaData('ToolBarItem');
        const radomNum = Math.random().toString().substr(2, 4);
        newButtonData.id = 'toolBarItem_' + radomNum;
        newButtonData.text = '新增按钮_' + radomNum;


        if (!treeNode.data.items) {
            treeNode.data.items = [newButtonData];
        } else {
            treeNode.data.items.push(newButtonData);
        }

        treeNode.children.push({ data: newButtonData, children: [], expanded: true });
        treeNode.expanded = true;

        const leftTreeNode = this.leftTree.serializedValue.find(v => v.node.data.id === treeNode.data.id);
        if (leftTreeNode) {
            leftTreeNode.node.children.push({ data: newButtonData, children: [], expanded: true });
            this.leftTree.loadData(this.leftTreeData);
        }
        this.rightTree.loadData(this.rightTreeData);
    }

    /**
     * 删除子级按钮
     */
    deleteChildButton(treeNode: any) {
        if (!treeNode.parent) {
            return;
        }
        const siblingNodes = treeNode.parent.children;
        const index = siblingNodes.findIndex(n => n.data.id === treeNode.data.id);
        if (index < 0) {
            return;
        }

        siblingNodes.splice(index, 1);

        treeNode.parent.data.items.splice(index, 1);

        const leftTreeNode = this.leftTree.serializedValue.find(v => v.node.data.id === treeNode.data.id);
        if (leftTreeNode) {
            leftTreeNode.parent.children.splice(index, 1);
            this.leftTree.loadData(this.leftTreeData);
        }
        this.rightTree.loadData(this.rightTreeData);

        if (this.selectedRightNode && this.selectedRightNode.data && this.selectedRightNode.data.id === treeNode.data.id) {
            this.propertyConfig = [];
        }

    }
    clickCancel() {
        this.closeModal.emit();
    }

    clickOK() {
        const toolbar = this.domService.module.toolbar;

        // 保存左侧全量按钮
        const allButtonItems = this.getButtonItemsFromTreeData(this.leftTreeData);
        toolbar.items[this.editorParams.viewModelId] = allButtonItems;

        // 保存右侧当前选中按钮
        const currentOccupiedButton = this.rightTreeData.map(d => d.data.id);
        if (!toolbar.configs[this.currentFormMode]) {
            toolbar.configs[this.currentFormMode] = {};
        }
        toolbar.configs[this.currentFormMode][this.editorParams.controlId] = currentOccupiedButton;

        this.webCmdService.syncActions();

        // 传递任意非空值，用于属性面板控件触发converter事件
        this.submitModal.emit({ value: null });

    }
    getButtonItemsFromTreeData(treeData: TreeNode[]) {
        const buttons = [];
        treeData.forEach((element: TreeNode | any) => {
            const nodeData = element.data;
            const { items, ...buttonInfo } = nodeData;
            buttonInfo.items = [];
            if (element.children && element.children.length) {
                const childButtons = this.getButtonItemsFromTreeData(element.children);
                buttonInfo.items.push(...childButtons);

            }
            buttons.push(buttonInfo);
        });

        return buttons;
    }


    propertyChanged(changeObject: PropertyChangeObject) {

        if (changeObject.propertyID === 'id') {
            const oldId = this.selectedRightNode.id;
            this.selectedRightNode.id = changeObject.propertyValue;

            const index = this.occupiedButtonIdList.findIndex(id => id === oldId);
            if (index > -1) {
                this.occupiedButtonIdList.splice(index, 1, changeObject.propertyValue);
            }
        }

        this.rightTree.loadData(this.rightTreeData);
        this.leftTree.loadData(this.leftTreeData);

        // 保存新增的变量
        this.addNewVariableToViewModel(changeObject, this.editorParams.viewModelId);
    }
    /**
     * 新版属性编辑器，在编辑过程中可能会新增变量，此处需要将新增的变量追加到ViewModel中
     */
    private addNewVariableToViewModel(changeObject: PropertyChangeObject, viewModelId: string) {
        const newPropertyValue = changeObject.propertyValue;
        if (newPropertyValue && newPropertyValue.isNewVariable && typeof newPropertyValue === 'object' &&
            newPropertyValue.type === 'Variable') {
            // 如果有则加入新变量
            delete newPropertyValue.isNewVariable;
            const newVar = {
                id: newPropertyValue.field,
                category: 'locale',
                code: newPropertyValue.path,
                name: newPropertyValue.path,
                type: newPropertyValue.newVariableType || 'String'
            };
            delete newPropertyValue.newVariableType;
            const viewModel = this.domService.getViewModelById(viewModelId);
            if (!viewModel.states.find(s => s.id === newVar.id)) {
                viewModel.states.push(newVar);
            }
        }
    }
}

// class NewToolbarItem {
//     id: string;
//     text: string;
//     isRootItem = true;
//     parent: any;
//     constructor() {
//         const radomNum = Math.random().toString().substr(2, 4);
//         this.id = 'toolBarItem_' + radomNum;
//         this.text = '新增按钮_' + radomNum;
//     }
// }

